package com.logic.modular.game.battle.info.roundInfo;

import com.baomidou.mybatisplus.extension.service.IService;
import com.logic.comment.util.XsRedisUtils;
import com.logic.modular.game.battle.info.roundInfo.domain.PvpBattleStatisticsInfo;
import com.logic.modular.game.battle.info.roundInfo.dto.PvpBattleStatisticsPlayerInfo;
import com.logic.modular.game.battle.panel.attribute.PlayerHeroAttributeServiceImpl;
import com.logic.modular.game.battle.panel.attribute.domain.PlayerHeroAttribute;
import com.logic.modular.game.player.match.PlayerPvpBattleLog;

import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.logic.modular.game.player.match.mapper.PvpBattleStatisticsInfoMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * pvp战斗统计信息
 *
 * @author cxy
 * @since 2024-09-05 14:56:05
 */
@Slf4j
@Service
public class PvpBattleStatisticsInfoServiceImpl extends ServiceImpl<PvpBattleStatisticsInfoMapper, PvpBattleStatisticsInfo> implements IService<PvpBattleStatisticsInfo> {
    private static final String RedisKey = "battle:%d:StatisticsInfo";
    @Resource
    private XsRedisUtils xsRedisUtils;
    @Resource
    private PlayerHeroAttributeServiceImpl playerHeroAttributeServiceImpl;

    public PvpBattleStatisticsInfo init(
            String battleUUID,
            Long currentMatchId,
            Long attackPlayerId,
            Long defPlayerId,
            Long defCityId
    ) {
        List<PlayerHeroAttribute> playerHeroAttributes = playerHeroAttributeServiceImpl.listCache(battleUUID);
        List<PlayerHeroAttribute> attackSide = playerHeroAttributes.stream()
                .filter(item -> Objects.equals(item.getUid(), attackPlayerId))
                .collect(Collectors.toList());
        List<PlayerHeroAttribute> defSide = playerHeroAttributes.stream()
                .filter(item -> Objects.equals(item.getUid(), defPlayerId))
                .collect(Collectors.toList());
        PvpBattleStatisticsInfo newBSI = new PvpBattleStatisticsInfo();
        newBSI.setMatchId(currentMatchId);
        newBSI.setBattleUid(battleUUID);
        newBSI.setCityId(defCityId);
        newBSI.setAttackPlayerUid(attackPlayerId);
        newBSI.setAttackPlayerInfo(PvpBattleStatisticsPlayerInfo.init(attackPlayerId, attackSide));
        newBSI.setDefendPlayerUid(defPlayerId);
        newBSI.setDefendPlayerInfo(PvpBattleStatisticsPlayerInfo.init(defPlayerId, defSide));
        newBSI.insert();
        saveCache(newBSI);
        // 记录战斗索引
        PlayerPvpBattleLog.logBattle(newBSI.getAttackPlayerUid(),
                newBSI.getBattleId());
        PlayerPvpBattleLog.logBattle(newBSI.getDefendPlayerUid(),
                newBSI.getBattleId());
        return newBSI;
    }

    public void saveCache(PvpBattleStatisticsInfo pvpBattleStatisticsInfo) {
        if (pvpBattleStatisticsInfo.getAttackPlayerInfo() == null) {
            throw new RuntimeException("攻击方英雄信息为空");
        }
        String key = String.format(RedisKey, pvpBattleStatisticsInfo.getBattleId());
        xsRedisUtils.set(key, pvpBattleStatisticsInfo, 12, TimeUnit.HOURS);
    }

    public PvpBattleStatisticsInfo selectCache(Long id) {
        String key = String.format(RedisKey, id);
        return xsRedisUtils.getToBean(key, PvpBattleStatisticsInfo.class);
    }

    @Override
    public boolean updateById(PvpBattleStatisticsInfo pvpBattleStatisticsInfo) {
        saveCache(pvpBattleStatisticsInfo);
        return true;
    }

    @Override
    public PvpBattleStatisticsInfo getById(Serializable id) {
        return selectCache(Long.valueOf(id.toString()));
    }

    public List<PvpBattleStatisticsInfo> battleStatisticsInfoList(
            @NotNull(message = "playerId不能为空") Long playerId
    ) {
        PlayerPvpBattleLog playerPvpBattleLog = PlayerPvpBattleLog.obtainBattleLog(playerId);
        return playerPvpBattleLog == null ? null : playerPvpBattleLog.battleIdSet.stream().map(this::getById).collect(Collectors.toList());
    }

    public void collection(Long battleId) {
        PvpBattleStatisticsInfo pvpBattleStatisticsInfo = new PvpBattleStatisticsInfo();
        pvpBattleStatisticsInfo.setBattleId(battleId);
        pvpBattleStatisticsInfo.setIsCollect(1);

        pvpBattleStatisticsInfo.updateById();
    }

    public void readCurrentIntraBureauCombatInformation(Long battleId) {
        PvpBattleStatisticsInfo pvpBattleStatisticsInfo = new PvpBattleStatisticsInfo();
        pvpBattleStatisticsInfo.setBattleId(battleId);
        pvpBattleStatisticsInfo.setIsRead(1);
        pvpBattleStatisticsInfo.updateById();
    }
}
